package cn.wenzy.aurora.framework.support.i18n.core;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.wenzy.aurora.framework.support.cache.CacheSupport;
import cn.wenzy.aurora.framework.support.i18n.properties.I18nProperties;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import org.apache.commons.lang3.LocaleUtils;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.context.NoSuchMessageException;

import java.text.MessageFormat;
import java.util.Locale;
import java.util.Optional;
import java.util.Properties;

public class I18nMessageSource implements MessageSource {

    private Locale defaultLocale;
    private I18nMessageLoader messageLoader;
    private CacheSupport cacheSupport;
    private boolean fromCache = false;
    private String redisKey;

    public I18nMessageSource(I18nMessageLoader messageLoader, I18nProperties i18nProperties, CacheSupport cacheSupport) {
        this.messageLoader = messageLoader;
        this.cacheSupport = cacheSupport;
        defaultLocale = LocaleUtils.toLocale(i18nProperties.getDefaultLocale());
        if (ObjectUtil.isNotNull(cacheSupport) && StrUtil.isNotBlank(i18nProperties.getRedisKey())) {
            fromCache = true;
            redisKey = i18nProperties.getRedisKey();
        }

    }

    @Override
    public String getMessage(@NotNull MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {
        String[] codes = resolvable.getCodes();
        Object[] args = resolvable.getArguments();
        if (ArrayUtil.isNotEmpty(codes)){
            for (String code : codes){
                String message = getMessage(code, args, locale);
                if (StrUtil.isNotBlank(message)){
                    return message;
                }
            }
        }
        return resolvable.getDefaultMessage();
    }

    @Override
    public String getMessage(@NotBlank String code, Object[] args, Locale locale) throws NoSuchMessageException {
        return getMessage(code, args, null, locale);
    }


    @Override
    public String getMessage(@NotBlank String code, Object[] args, String defaultMessage, Locale locale) {
        if (StrUtil.isBlank(code)){
            return defaultMessage;
        }
        Locale tempLocale = Optional.ofNullable(locale).orElse(defaultLocale);
        if (fromCache){
            String key = redisKey.concat(StrUtil.COLON).concat(tempLocale.toString());
            String message = cacheSupport.getMapChild(key, code);
            if (StrUtil.isNotBlank(message)){
                return MessageFormat.format(message, args);
            }
        }

        Properties properties = messageLoader.getProperties(tempLocale);
        if (ObjectUtil.isNull(properties)) {
            return defaultMessage;
        }
        String message = properties.getProperty(code);
        if (StrUtil.isBlank(message)){
            return defaultMessage;
        }
        return MessageFormat.format(message, args);
    }



}
